package com.authsphere.plugin.wrapper;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;

import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;

/**
 * @program: AuthSphere
 * @description:
 * @author: YuKai Fan
 * @create: 2025/3/28 16:43
 **/
public class ModifiableHttpServletRequest extends HttpServletRequestWrapper {
    private final Map<String, String[]> parameters;
    private final Map<String, String> headers;
    private List<Cookie> cookies;

    public ModifiableHttpServletRequest(HttpServletRequest request) {
        super(request);
        this.parameters = Maps.newHashMap(request.getParameterMap());
        this.headers = Maps.newHashMap();
        this.cookies = Lists.newArrayList();
        Enumeration<String> headerNames = request.getHeaderNames();
        if (headerNames != null) {
            while (headerNames.hasMoreElements()) {
                String headerName = headerNames.nextElement();
                this.headers.put(headerName, request.getHeader(headerName));
            }
        }

        Cookie[] originalCookies = request.getCookies();
        if (originalCookies != null) {
            for (Cookie cookie : originalCookies) {
                this.cookies.add(new Cookie(cookie.getName(), cookie.getValue()));
            }
        }
    }

    public void addParameter(String name, String value) {
        parameters.put(name, new String[] {value});
    }

    @Override
    public String getParameter(String name) {
        String[] values = parameters.get(name);
        if (values == null || values.length == 0) {
            return null;
        }
        return values[0];
    }

    @Override
    public Map<String, String[]> getParameterMap() {
        return Collections.unmodifiableMap(parameters);
    }

    @Override
    public Enumeration<String> getParameterNames() {
        return Collections.enumeration(parameters.keySet());
    }

    @Override
    public String[] getParameterValues(String name) {
        return parameters.get(name);
    }

    public void addHeader(String name, String value) {
        headers.put(name, value);
    }

    @Override
    public String getHeader(String name) {
        return headers.get(name);
    }

    @Override
    public Enumeration<String> getHeaders(String name) {
        String value = getHeader(name);
        if (value != null) {
            return Collections.enumeration(Collections.singletonList(value));
        }
        return Collections.emptyEnumeration();
    }

    @Override
    public Enumeration<String> getHeaderNames() {
        return Collections.enumeration(headers.keySet());
    }


    public void addCookie(Cookie cookie) {
        // Remove existing cookie with the same name
        cookies.removeIf(c -> c.getName().equals(cookie.getName()));
        cookies.add(cookie);
    }

    @Override
    public Cookie[] getCookies() {
        return cookies.toArray(new Cookie[0]);
    }
}
